Skip to content

feat: workspace owners can permanently delete a channel - #257

Open
sercada wants to merge 3 commits into
openclaw:mainfrom
sercada:feat/delete-channels
Open

sercada wants to merge 3 commits into
openclaw:mainfrom
sercada:feat/delete-channels

Conversation

@sercada

@sercada sercada commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor
Maintainer edits

MUST: Keep Allow edits from maintainers enabled for this PR.

What Problem This Solves

Archiving hides a channel while retaining its history. Owners need an explicit way to remove an unwanted channel and its exclusively owned files permanently.

User Impact

User impact: owners review the affected messages and files, type the exact channel name, and delete it. People viewing that channel move to a remaining channel with a notice. Archive remains available. The final channel cannot be deleted; moderators, members, bot tokens, and former owners cannot delete one.

Permanent deletion remains a product and public API decision for maintainers before merge.

Why This Change Was Made

The authenticated store transaction checks current ownership, removes channel-owned rows, and publishes one durable workspace event. Exclusive file deletion uses durable cleanup and rechecks references, so content retained by another channel survives. SQLite search row IDs make the cascade bounded while preserving search on retained messages and old event cursors.

Clients retain deletion facts and filter late channel-list and search-page responses, including IDs not yet in their sidebar. The HTTP response and its event are reconciled once, preserving the original notice. Already-open channel and thread embeds retire reads, sends, sockets, history, and composers, then show a terminal deleted state.

Evidence

Refreshed onto upstream main, retaining its owner-only channel administration, current SQLC, push/sidebar support, and embedded asset generation. Migration filenames retain their original identities for earlier feature builds.

The official v0.7.0 and latest v0.7.1 binaries populated independent SQLite and PostgreSQL fixtures with channels, root and thread messages, searchable history, and exclusive/retained uploads. Restarting the candidate on the same databases produced these results through the shipped clickclack serve entry point:

Action SQLite and PostgreSQL result
Upgrade v0.7.0 and v0.7.1 → candidate Channel/message/upload/event counts unchanged; earlier thread, search, and exact file bytes readable
Moderator DELETE HTTP 403; rows and exclusive file unchanged; no cleanup job or durable event
Former owner DELETE after committed ownership transfer HTTP 403 with the same unchanged data, file, cleanup, and event evidence
Current owner DELETE HTTP 204; deleted rows and exclusive physical file gone; another channel, its file, and search retained; earlier event cursor replays channel.deleted

Shared store regressions and HTTP/CLI deletion checks pass, including PostgreSQL locking/concurrency and moderator/ownership-transfer rejection with the current-owner positive control. Web/SDK/embedded build and workspace typechecks pass.

Seven focused Chromium regressions pass: exact-name owner confirmation and original notice, member evacuation, final-channel rejection, held stale channel list, held first/next search pages, and already-open channel/thread embeds. A separate actual-server capture confirmed both before/after views below. All six images were inspected; they contain only synthetic Local Captain fixtures. T3 preview explicitly reported no connected browser host, so repository Playwright supplied the browser proof. No deployment is claimed.

Actual sanitized SQLite upgrade transcript · PostgreSQL transcript · Evidence provenance

Before deletion After deletion
Owner reviews exact-name confirmation Owner reaches general with original deletion notice
Open channel embed contains history and composer Channel embed retires history and composer
Open thread embed contains root, reply, and composer Thread embed becomes terminal

The canonical autoreview helper completed all four passes against the complete candidate with no P0–P2 findings. Independent manual review of the client reconciliation and embed retirement also found no actionable issue. These source reviews do not grant maintainer acceptance of permanent deletion, which remains open.

Latest stable repeat: v0.7.1 SQLite native transcript · PostgreSQL native transcript. The final candidate binary was rebuilt for this repeat; all retained-state and current-ownership final effects passed, and private PostgreSQL fixtures were stopped.

Exact-name confirmation is covered through the shipped browser: the delete button remains disabled for an incomplete name and becomes enabled for the exact name. The redundant helper-only comparison test has been removed; the seven browser regressions remain. This follow-up changes only test inventory, so the linked serve, upgrade and browser evidence still describes the current production source. Current-head CI must finish independently.

@sercada
sercada requested a review from a team as a code owner September 13, 2026 12:33
@clawsweeper

clawsweeper Bot commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Sep 13, 2026
@clawsweeper

clawsweeper Bot commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: blocked before merge.

What this changes

This PR lets workspace owners permanently delete channels through the browser, API, SDK, and CLI, removing exclusively owned content and updating connected clients.

Example: An owner removes #doomed while #general remains.

  • Before: Archiving hides #doomed but retains its messages and files.
  • After: The owner reviews the preview, types doomed, and deletes the channel; viewers move to #general, exclusive files are removed, and shared files survive.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) Strong shipped-entry-point and upgrade evidence supports a coherent implementation with no actionable findings; unresolved product acceptance caps overall readiness.
Proof confidence 🦞 diamond lobster (5/6) ✨ media proof bonus Sufficient (linked_artifact): Inspected browser captures exercise actual synthetic-server owner deletion and terminal channel/thread embeds; SQLite and PostgreSQL clickclack serve transcripts cover stable upgrades, forbidden moderator and former-owner final effects, successful current-owner removal, retained files/search, and event replay.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Feature · Worth it: Needs a maintainer decision · Fix scope: Complete
User problem: Owners can hide unwanted channels through archival but cannot permanently remove their history and exclusively owned files.
Reason: The implementation addresses a concrete lifecycle need, but irreversible removal, new endpoints, SDK methods, and a persistent search-row mapping need owner direction.

Merge readiness

⛔ Blocked before merge - 1 item remains

Keep this PR open: permanent channel deletion is absent from current main, and the implementation merits consideration, but its destructive product and public API contract still needs maintainer acceptance.

Priority: P2
Reviewed head: 7443b01433b7160b6d004588c7062fb7c35803c1
Owner decision: Required. See Decision needed.

Decision needed

  • Question: Should ClickClack expose permanent owner-only channel deletion through the browser, API, SDK, and CLI with the retention and protection rules implemented here?
  • Recommendation: Accept the implemented contract: Approve owner-only deletion with preview, browser name confirmation, final-channel and Guests protection, shared-file retention, durable cleanup, and client retirement.
  • Why: Archival is an established reversible capability, while this PR introduces irreversible removal and a new public lifecycle contract without recorded maintainer acceptance.

Before merge

  • Resolve maintainer decision - Resolve the maintainer decision shown above before merge.

Findings

None.

Agent review details

How this fits together

Browser, CLI, and SDK requests enter the authenticated HTTP API; SQLite or PostgreSQL transactions authorize deletion and remove channel-owned rows, then durable events update clients and queued cleanup removes exclusive upload objects.

flowchart TD
  A[Browser CLI and SDK] --> B[Authenticated HTTP API]
  B --> C[Current owner transaction]
  C --> D[SQLite or PostgreSQL]
  C --> E[Durable deletion event]
  C --> F[Upload cleanup queue]
  E --> G[Chat and embed clients]
  F --> H[Upload storage]
Loading

Technical review

Best possible solution:

Have the channel area owner accept the implemented owner-only deletion contract or specify a narrower supported scope.

Do we have a high-confidence way to reproduce the issue?

This is a feature request rather than a current-main bug; source confirms that existing channel archival retains history, while the supplied browser and serve evidence exercises the proposed permanent deletion.

Is this the best way to solve the issue?

The implementation puts authorization and deletion in the shared store boundary, reuses durable upload cleanup, and preserves existing archive behavior; accepting the new destructive capability remains a product decision.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against fe0850b11d86.

Provenance checked

Testing

Proof path: shipped entry point.

Security

None.

Evidence

What I checked:

  • Current main has no permanent channel deletion endpoint: The default-branch channel handlers provide listing and creation, while the pinned introduced diff adds DELETE and deletion-preview routes; archival remains a separate existing capability. (apps/api/internal/httpapi/server.go:246, 7443b01433b7)
  • Authorization precedes destructive effects: The HTTP boundary rejects bot tokens; both stores check current workspace ownership inside the deletion transaction before removing uploads, enqueueing cleanup, deleting the channel, or appending its event. (apps/api/internal/httpapi/channels.go:160, 7443b01433b7)
  • Shared content and final-channel protection: PostgreSQL serializes competing channel deletions, locks candidate uploads, and rereads their references; shared uploads and workspace icons are excluded, and both stores reject deletion of the last or provisioned Guests channel. (apps/api/internal/store/postgres/channel_deletion.go:51, 7443b01433b7)
  • Client reconciliation and browser coverage: Retained deletion IDs filter late channel-list and search responses; existing read owners retire open embeds. Seven browser cases cover confirmation, evacuation, protection, delayed responses, and both embed surfaces. (tests/e2e/channel-deletion.spec.ts:38, 7443b01433b7)
  • Inspected browser proof: Inspected all six linked synthetic-server screenshots: owner confirmation and subsequent #general notice, plus channel and thread embeds before deletion and their terminal deleted views afterward. Artifact provenance identifies production source 0c3cadc. (delete-channels-20261013/README.md:3, 10f57e0c0da7)
  • Latest stable upgrade and final-effect proof: Read the linked v0.7.1 SQLite and PostgreSQL serve transcripts: preexisting counts, history, search, and file bytes survive upgrade; moderator and former-owner requests return 403 without row, file, cleanup, or event changes; the current owner receives 204 with exclusive content removed and retained content and event replay preserved. (delete-channels-20261013/upgrade-v071-sqlite.txt:1, adec389045c8)

Labels

Label changes:

No label changes.

Label justifications:

  • P2: This is a useful channel lifecycle feature with limited scope and no established urgent regression.
  • merge-risk: 🚨 compatibility: The additive API and SDK expose an irreversible channel lifecycle operation whose permanent contract requires maintainer acceptance; supplied upgrade evidence clears the storage migration gate.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • proof: sufficient: Contributor real behavior proof is sufficient.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

History

Review history (36 earlier review cycles; latest 8 shown)
  • reviewed 2026-10-13T08:26:20.220Z sha 0c3cadc :: needs real behavior proof before merge. :: none
  • reviewed 2026-10-13T08:56:02.634Z sha 0c3cadc :: blocked before merge. :: none
  • reviewed 2026-10-13T14:57:56.858Z sha 0c3cadc :: blocked before merge. :: none
  • reviewed 2026-10-13T19:23:26.511Z sha 7443b01 :: blocked before merge. :: none
  • reviewed 2026-10-14T00:55:24.714Z sha 7443b01 :: blocked before merge. :: none
  • reviewed 2026-10-14T02:04:54.465Z sha 7443b01 :: blocked before merge. :: none
  • reviewed 2026-10-14T05:32:22.725Z sha 7443b01 :: blocked before merge. :: none
  • reviewed 2026-10-14T09:05:51.318Z sha 7443b01 :: blocked before merge. :: none

Reviewed October 14, 2026, 10:03 AM ET / 14:03 UTC (Revision 37).

@sercada
sercada force-pushed the feat/delete-channels branch from b6d6079 to aa459dd Compare September 13, 2026 12:57
Owners delete a channel from Channel settings, the API, or the CLI after
reviewing what will be removed and typing the channel name. The channel's
messages, replies, reactions, pins, topics, read state, and exclusive uploads
go in one transaction; a workspace-scoped channel.deleted event moves viewers
out. The last channel and the Guests workspace's provisioned channels cannot
be deleted. The CLI deletes only a channel named with --channel on its command
line, never CLICKCLACK_CHANNEL or the saved default.

On SQLite, cascading many message deletions scanned both the messages table
and the FTS index once per row. Child-key indexes and a message-to-search-row
map make a 10k-message channel in a 120k-message workspace delete in 0.3 s
instead of 6.6 minutes, which also speeds up workspace deletion.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@sercada
sercada force-pushed the feat/delete-channels branch from aa459dd to c6d1ef8 Compare September 13, 2026 13:27
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. labels Sep 13, 2026
@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 session-state 🚨 Merging this PR could lose, corrupt, stale, or mis-associate session or agent state. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Oct 8, 2026
@clawsweeper clawsweeper Bot added merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. and removed proof: sufficient Contributor real behavior proof is sufficient. labels Oct 11, 2026
@sercada

sercada commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Updated this PR to 0c3cadcc on current main and addressed the three client findings:

  • Late channel-list and first/next search responses reconcile against retained deletion facts, including events for an ID not yet in the sidebar.
  • Open channel and thread embeds retire pending reads/sends, clear history/composers, and show a terminal deleted state.
  • The owner's HTTP response and realtime echo now share one notice; the browser proof caught and fixed the duplicate-event overwrite.

All seven focused Chromium cases pass. The PR body now embeds inspected before/after captures from the actual synthetic server, plus readable SQLite and PostgreSQL v0.7.0 upgrade transcripts. Those native serve runs also prove moderator and former-owner 403 preserve channel/message/upload rows, exact exclusive file bytes, cleanup jobs, and events; the committed current owner then succeeds with 204, while another channel/file/search and the earlier event cursor survive.

The canonical helper completed all four passes with no P0–P2 findings, and the client repair received separate manual review. Source reviews and these fixtures do not grant product/API acceptance or imply a deployment. Permanent deletion remains a maintainer decision; I have left that merge gate open.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. proof: sufficient Contributor real behavior proof is sufficient. and removed merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. merge-risk: 🚨 session-state 🚨 Merging this PR could lose, corrupt, stale, or mis-associate session or agent state. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Oct 13, 2026
@sercada

sercada commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

The latest review identifies permanent-deletion acceptance as the remaining product gate. I recommend accepting the implemented owner-only contract: preview, exact-name browser confirmation, final-channel protection, transactional current-owner authorization, retained-file handling, and retirement of open clients/embeds.

I also removed the low-value helper-only comparison test noted in that review (7443b01433b7); the shipped-browser confirmation regression remains, production source is unchanged, and a canonical local-delta P0–P2 review is clean. Exact-head CI is now green: all 10 checks succeed. The latest hosted review still reports sufficient native/browser/upgrade evidence and no actionable findings; the product/API decision remains unresolved.

Could the channel area owner record acceptance of this contract, or specify the concrete scope to narrow? The native SQLite/PostgreSQL upgrade and denial/allowed final-effect transcripts and inspected browser captures are linked in the PR body. That product decision remains open; I am not treating automated review as approval.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant